//
//  SEGPgcManager.m
//  FrameworkTest
//
//  Created by 刘山 on 2018/4/18.
//  Copyright © 2018年 刘山. All rights reserved.
//

#import "SEGPgcManager.h"
#import "CommomHeader.h"
#import <SEGPlatform/SEGAdDisplayManager.h>
#import "SEGPgcIDManager.h"

#if __has_include(<Commom/SEGProfileManager.h>)
#import <Commom/SEGProfileManager.h>
#else
#import "SEGProfileManager.h"
#endif

/*
 1.数据组件刷新控件：
 [OK]最新一组数据与历史浏览间嵌入一个刷新控件，文案：上次看到这里，点击刷新
 [OK]页面底部嵌入一个刷新控件，文案：到底了，点击刷新
 
 [OK]2.设置多处刷新控件，便于用户在浏览时，更方便的刷新页面，获取新内容；刷新后的数据保存到最顶部
 
 3.底部tab-刷新：
 [OK]用户停留带纷享首页时，底部按钮改成“刷新”，点击即刷新首页列表；
 [OK]用户切换到其他模块，底部按钮变成“纷享”；
 [OK]4.每次刷新成功后，列表顶部增加动态tip提示：为您刷新7篇内容；
 [OK]5.缓存最新三组数据
 */

@interface SEGPgcManager()
@property (nonatomic, assign) NSUInteger __block adverIndex; ///< 记录广告的下标
@end

@implementation SEGPgcManager

/**
 * 从本地获取PGC数据
 * @author Sam
 */
-(void)segPGCLayoutFromLocal {
    // 没有数据的时候也要添加一个刷新占位mdoel
    NSArray<SEGPgcListModel*>* localData = [self segGetPgc];
    // 组合各组数据并插入广告占位数据
    NSArray<SEGPgcRecommendModel *> *recommendArray = [self segPGCDataSectionsToRows:localData];
    // 新老数据组合并添加刷新占位数据
    recommendArray = [self segCombineNewData:nil oldData:recommendArray];
    self.pgcModelArray = recommendArray;
    self.freshCount = 0;
}

/**
 * 请求推荐PGC数据
 * 获取服务器推荐数据
 * @author Sam
 * @version 4.6.0
 */
-(void)segRequestRecommendPGCFinished:(SEGNetworkReponse)finished {
    // 请求PGC推荐数据
    [self segAutoRequestPgcDataFinished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
        dispatch_queue_t queue = dispatch_queue_create("com.uhome.pgc.auto", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            
            SEGPgcListModel* data = result;
            
            if (isSuccessed && data.recommend.count > 0) {
                
                //返回正常的服务器中PGC数据展示规则：推荐数据+本地缓存数据
                NSArray<SEGPgcListModel*>* localData = [self segGetPgc];
                
                // 组合本地数据并插入广告占位数据
                NSArray<SEGPgcRecommendModel *> *localRecommendArray = [self segPGCDataSectionsToRows:localData];
                // 组合推荐数据并插入广告占位数据
//                NSArray<SEGPgcRecommendModel *> *newRecommendArray = [self segPGCDataSectionsToRows:@[data]];
                
                // 组合推荐数据并插入广告占位数据
                NSArray<SEGPgcRecommendModel *> *newRecommendArray = [self segHandleRecommendPGCData:data.recommend];
                
                // 新老数据组合并添加刷新占位数据
                NSArray<SEGPgcRecommendModel *> *combinedRecommendArray = [self segCombineNewData:newRecommendArray oldData:localRecommendArray];
                self.pgcModelArray = combinedRecommendArray;
                self.freshCount = 0;
                
                // 如果要展示广告，则提示的刷新数据要加一，因为广告会占位一位
//                self.freshCount = data.recommend.count + ([data.advIdent isEqualToString:@"1"] ? 1 : 0);
                
                // 刷新提示要加上广告个数
                self.freshCount = newRecommendArray.count;
                
                //保存推荐数据
                [self segSavePgc:data];
                finished(YES,result,codeType,errorMessage);
                return;
            }
            
            // 查询失败 则读取本地数据
            [self segPGCLayoutFromLocal];
            
            self.freshCount = 0;
            finished(NO,nil,codeType,errorMessage);
            return;
        });
    }];
}


/**
 * 手动刷新数据展示
 * @author Sam
 * @param page  页数
 */
-(void)segRefreshPgcDataWithPageNo:(NSInteger)page finished:(SEGNetworkReponse)finished {
    self.freshCount = 0;
    [self segRefreshPgcDataByHandWithPageNo:page Finished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
        
        dispatch_queue_t queue = dispatch_queue_create("com.uhome.pgc.manual", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            
            SEGPgcListModel* data = result;
            if (isSuccessed && data && data.recommend.count > 0) {
                [self segSavePgc:data];
            }
            
            // 组合推荐数据并插入广告占位数据
            // 处理数据异常情况
            NSArray<SEGPgcRecommendModel *> *newRecommendArray = data ? [self segPGCDataSectionsToRows:@[data]] : nil;

            // 拼接新老数据
            NSArray<SEGPgcRecommendModel *> *combinedData = [self segCombineNewData:newRecommendArray oldData:self.pgcModelArray];
            self.pgcModelArray = combinedData;
            
            self.freshCount = newRecommendArray.count;
            
            dispatch_async(dispatch_get_main_queue(), ^{
                finished(YES,data,codeType,errorMessage);
                return;
            });
        });
    }];
}


/// 手动刷新PGC列表 根据ID请求PGC实体
/// @param pgcID pgcID数组
/// @param finished finished
-(void)segRefreshPgcDataWithID:(NSArray *)pgcID finished:(SEGNetworkReponse)finished {
    self.freshCount = 0;
    NSString *dailyID = [pgcID componentsJoinedByString:@","];
    NSDictionary *paramters = @{@"dailyId" : ValueToString(dailyID)};
    NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/cms-api/index/daily/getDailyDetail",nil];
    [SEGHTTPBusinessManager seg_requestWithMethod:GET URLString:urlString parameters:paramters finished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
        dispatch_queue_t queue = dispatch_queue_create("com.uhome.pgc.manual", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            
            SEGPgcListModel* data = nil;
            if (isSuccessed && [result[@"data"] isKindOfClass:[NSDictionary class]]) {
                // 请求PGC实体之后 更新PGC ID缓存
                [[SEGPgcIDManager shared] updateLocalIDWithAlreadyUsedID:pgcID];
                // 模型转换
                data = [SEGPgcListModel yy_modelWithDictionary:result[@"data"]];
            }
            
            // 保存数据
            if (data && data.recommend.count > 0) {
                [self segSavePgc:data];
            }
            
            // 组合推荐数据并插入广告占位数据
            NSArray<SEGPgcRecommendModel *> *newRecommendArray = data ? [self segPGCDataSectionsToRows:@[data]] : nil;

            // 拼接新老数据
            NSArray<SEGPgcRecommendModel *> *combinedData = [self segCombineNewData:newRecommendArray oldData:self.pgcModelArray];
            self.pgcModelArray = combinedData;
            
            // 提示刷新的数量包含广告数量
            self.freshCount = newRecommendArray.count;
            
            dispatch_async(dispatch_get_main_queue(), ^{
                if (isSuccessed && data && data.recommend.count > 0) {
                    finished(YES,data,codeType,errorMessage);
                } else {
                    finished(NO,data,codeType,errorMessage);
                }
                return;
            });
        });
    }];
}

#pragma mark - 手动、自动 拉取PGC数据的基本网络请求
/**
 * 自动拉取推荐数据
 * @author Sam
 */
-(void)segAutoRequestPgcDataFinished:(SEGNetworkReponse)finished{
    NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/cms-api/api/v2/index",nil];
    [SEGHTTPBusinessManager seg_requestWithMethod:GET
                                        URLString:urlString
                                       parameters:@{@"code":@(SEGEnumAdvertismentIdType_PGC_RECOMMEND)}
                                         finished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
                                             [self segResponseisSuccessed:isSuccessed result:result codeType:codeType errorMessage:errorMessage finished:finished];
                                         }];
}

/**
 * 手动拉取推荐数据
 * @author Sam
 */
-(void)segRefreshPgcDataByHandWithPageNo:(NSInteger)page Finished:(SEGNetworkReponse)finished{
    NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/cms-api/api/v2/manuaRefresh",nil];
    [SEGHTTPBusinessManager seg_requestWithMethod:GET
                                        URLString:urlString
                                       parameters:@{@"code":@(SEGEnumAdvertismentIdType_PGC_HANDFRESH)}
                                         finished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
                                             [self segResponseisSuccessed:isSuccessed result:result codeType:codeType errorMessage:errorMessage finished:finished];
                                         }];
}

-(void)segResponseisSuccessed:(BOOL)isSuccessed result:(id)result codeType:(NSString*)codeType errorMessage:(NSString*)errorMessage finished:(SEGNetworkReponse)finished{
    
    if (!isSuccessed) {
        finished(NO,nil,codeType,errorMessage);
        return;
    }
    
    NSDictionary *data = [result valueForKey:@"data"];
    if (!(data && [data isKindOfClass:[NSDictionary class]])) {
        finished(NO,nil,codeType,errorMessage);
        return;
    }
    
    SEGPgcListModel *pgcData = [SEGPgcListModel yy_modelWithDictionary:data];
    finished(YES,pgcData,codeType,errorMessage);
    return;
}

#pragma mark - PGC数据本地缓存

/**
 * 保存PGC数据到本地
 * 保存最新三组数据
 * @author Sam
 */
-(void)segSavePgc:(SEGPgcListModel*)data{
    if (!data || data.recommend.count <= 0) return;
    
    NSMutableArray<SEGPgcListModel*> *arrM = [NSMutableArray array];
    
    //获取本地数组
    NSArray<SEGPgcListModel*> *arr = [self segGetPgc];
    [arrM addObject:data];
    
    //只取前三组数据
    [arr enumerateObjectsUsingBlock:^(SEGPgcListModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (idx <= 1) {
            [arrM addObject:obj];
        }else{
            *stop = YES;
        }
    }];
    
    // 保存最新三组数据
    [NSKeyedArchiver archiveRootObject:arrM toFile:[self segpgcLocalPath]];
}

/**
 * 获取PGC数据到本地
 * 保存最新三组数据
 * @author Sam
 */
-(NSArray<SEGPgcListModel*>*)segGetPgc{
    return [NSKeyedUnarchiver unarchiveObjectWithFile:[self segpgcLocalPath]];
}

/**
 * 本地PGC路径
 * @author Sam
 */
-(NSString*)segpgcLocalPath{
    NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    return [filePath stringByAppendingPathComponent:[NSString stringWithFormat:@"SEGArchiver%@PGC.data",kAccountUserID]];
}

#pragma mark - 数据处理

/**
 把请求到的服务器数据和本地缓存中的数据拼接在一起
 
 @param newData 服务器请求的新数据
 @param oldData 本地缓存的数据
 @return 拼接之后的数据
 */
- (NSArray<SEGPgcRecommendModel*>*)segCombineNewData:(NSArray<SEGPgcRecommendModel*>*)newData oldData:(NSArray<SEGPgcRecommendModel*>*)oldData {
    
    NSInteger __block adverTotal = 0; // 记录广告总数
    
    // 1.先过滤掉数据里面的刷新占位数据
    NSMutableArray<SEGPgcRecommendModel *> *tempNewData = [NSMutableArray array];
    for (SEGPgcRecommendModel *recommendModel in newData) {
        if ([recommendModel.pgcWidgetType integerValue] != SEGEnumPgcWidgetType_RefreshMiddle && [recommendModel.pgcWidgetType integerValue] != SEGEnumPgcWidgetType_RefreshBottom) {
            [tempNewData addObject:recommendModel];
            if ([recommendModel.pgcWidgetType integerValue] == SEGEnumPgcWidgetType_AD) {
                adverTotal ++;
            }
        }
    }
    
    NSMutableArray<SEGPgcRecommendModel *> *tempOldData = [NSMutableArray array];
    for (SEGPgcRecommendModel *recommendModel in oldData) {
        if ([recommendModel.pgcWidgetType integerValue] != SEGEnumPgcWidgetType_RefreshMiddle && [recommendModel.pgcWidgetType integerValue] != SEGEnumPgcWidgetType_RefreshBottom) {
            [tempOldData addObject:recommendModel];
            if ([recommendModel.pgcWidgetType integerValue] == SEGEnumPgcWidgetType_AD) {
                adverTotal ++;
            }
        }
    }
    
    // 2.拼接数据
    NSMutableArray<SEGPgcRecommendModel *> *resultData = [NSMutableArray arrayWithArray:tempNewData];
    // 3.添加头部刷新占位数据
    if (tempNewData.count > 0 && tempOldData.count > 0) {
        SEGPgcRecommendModel *headerRefresh = [[SEGPgcRecommendModel alloc] init];
        headerRefresh.pgcWidgetType = @(SEGEnumPgcWidgetType_RefreshMiddle).stringValue;
        [resultData addObject:headerRefresh];
    }
    [resultData addObjectsFromArray:tempOldData];
    
    // 4.添加底部刷新占位数据
    SEGPgcRecommendModel *footerRefresh = [[SEGPgcRecommendModel alloc] init];
    footerRefresh.pgcWidgetType = @(SEGEnumPgcWidgetType_RefreshBottom).stringValue;
    [resultData addObject:footerRefresh];
    
    // 5.处理广告index，将顺序置位逆序
    [resultData enumerateObjectsUsingBlock:^(SEGPgcRecommendModel * _Nonnull recommendModel, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([recommendModel.pgcWidgetType integerValue] == SEGEnumPgcWidgetType_AD) {
            adverTotal --;
            recommendModel.adverIndex = adverTotal;
        }
    }];
    
    return [resultData copy];
}

/**
 * 把PGC多组数据组合成一组便于展示,并添加广告占位数据
 * @author Sam
 */
-(NSArray<SEGPgcRecommendModel*>*)segPGCDataSectionsToRows:(NSArray<SEGPgcListModel*>*)sections{
    if (!sections || sections.count <=0)return nil;
    NSMutableArray<SEGPgcRecommendModel*> *originPGCList = [NSMutableArray array];
    NSMutableArray<SEGPgcRecommendModel*> *handlePGCList = [NSMutableArray array];
    
    // 先将多组数据合并为一组
    [sections enumerateObjectsUsingBlock:^(SEGPgcListModel * _Nonnull sectionModel, NSUInteger idx, BOOL * _Nonnull stop) {
        [sectionModel.recommend enumerateObjectsUsingBlock:^(SEGPgcRecommendModel * _Nonnull pgcModel, NSUInteger idx, BOOL * _Nonnull stop) {
            [originPGCList addObject:pgcModel];
        }];
    }];
    
    /*
     插入广告逻辑
    1.M为一组，每组第N个位置展示广告;
      eg.M=1 N=1，那么数据为：广告、数据、广告、数据.....
    2.M>0 N>0 M>=N
    3.当前组不够M个的时候，不展示广告
    */
    SEGAdDisplayModel *adDisplayModel = [[SEGAdDisplayManager shared] getLoopAdDisplayModel:SEGAD_PGCListType];

    if (adDisplayModel && adDisplayModel.groupCount > 0 && adDisplayModel.showAdvCount > 0 && adDisplayModel.groupCount >= adDisplayModel.showAdvCount) {
        
        NSInteger __block adverIndex = 0;
        NSInteger __block currentIndex = 1;
        NSInteger __block lastGroupIndex = originPGCList.count / adDisplayModel.groupCount * adDisplayModel.groupCount;
        
        // 插入广告
        [originPGCList enumerateObjectsUsingBlock:^(SEGPgcRecommendModel * _Nonnull pgcModel, NSUInteger idx, BOOL * _Nonnull stop) {
            // 不是最后一组 就插入广告
            if (currentIndex == adDisplayModel.showAdvCount && idx < lastGroupIndex) {
                SEGPgcRecommendModel *adModel = [[SEGPgcRecommendModel alloc] init];
                adModel.pgcWidgetType = @(SEGEnumPgcWidgetType_AD).stringValue;
                adModel.adverIndex = adverIndex;
                adverIndex++;
                [handlePGCList addObject:adModel];
            }
            [handlePGCList addObject:pgcModel];
            
            // 计算下标 超过一组就重置
            currentIndex ++;
            if (currentIndex > adDisplayModel.groupCount) {
                currentIndex = 1;
            }
        }];
    } else {
        handlePGCList = originPGCList;
    }
    
    // 老版插入广告逻辑 每组固定位置
//    [sections enumerateObjectsUsingBlock:^(SEGPgcListModel * _Nonnull objSec, NSUInteger idxSec, BOOL * _Nonnull stopSec) {
//        [objSec.recommend enumerateObjectsUsingBlock:^(SEGPgcRecommendModel * _Nonnull objRow, NSUInteger idxRow, BOOL * _Nonnull stopRow) {
//        /*PGC如果SEGPgcListModel中广告值为1说明有广告，就把广告插入到SEGPgcRecommendModel中第4位，如果数据小于4位就插入到最后一条*/
//            if ([objSec.advIdent isEqualToString:@"1"] && objSec.recommend.count >= 4 && idxRow == 3) {
//                SEGPgcRecommendModel *tmp = [[SEGPgcRecommendModel alloc]init];
//                tmp.pgcWidgetType = @(SEGEnumPgcWidgetType_AD).stringValue;
//                // 设置广告的下标
//                tmp.adverIndex = adverIndex;
//                adverIndex ++;
//                [retM addObject:tmp];
//            }
//
//            objRow.pgcWidgetType = @(SEGEnumPgcWidgetType_PGC).stringValue;
//            [retM addObject:objRow];
//        /*PGC如果SEGPgcListModel中广告值为1说明有广告，就把广告插入到SEGPgcRecommendModel中第4位，如果数据小于4位就插入到最后一条*/
//            if ([objSec.advIdent isEqualToString:@"1"] && objSec.recommend.count < 4 && idxRow == objSec.recommend.count - 1) {
//                SEGPgcRecommendModel *tmp = [[SEGPgcRecommendModel alloc]init];
//                tmp.pgcWidgetType = @(SEGEnumPgcWidgetType_AD).stringValue;
//                // 设置广告的下标
//                tmp.adverIndex = self.adverIndex;
//                self.adverIndex ++;
//                [retM addObject:tmp];
//            }
//
//        }];
//    }];
    
    return handlePGCList;
}


/// 处理推荐数据列表 插入广告
/// @param recommendList 推荐列表
-(NSArray<SEGPgcRecommendModel*>*)segHandleRecommendPGCData:(NSArray<SEGPgcRecommendModel*>*)recommendList {
    if (!recommendList || recommendList.count == 0) {
        return recommendList;
    }
    
    /*
    插入广告逻辑
    1.M为一组，每组第N个位置展示广告;
        eg.M=1 N=1，那么数据为：广告、数据、广告、数据.....
    2.M>0 N>0 M>=N
    3.当前组不够M个的时候，不展示广告
    */
    SEGAdDisplayModel *adDisplayModel = [[SEGAdDisplayManager shared] getLoopAdDisplayModel:SEGAD_PGCRecommendType];

    if (adDisplayModel && adDisplayModel.groupCount > 0 && adDisplayModel.showAdvCount > 0 && adDisplayModel.groupCount >= adDisplayModel.showAdvCount) {
        NSMutableArray<SEGPgcRecommendModel*> *handlePGCList = [NSMutableArray array];
        NSInteger __block adverIndex = 0;
        NSInteger __block currentIndex = 1;
        NSInteger __block lastGroupIndex = recommendList.count / adDisplayModel.groupCount * adDisplayModel.groupCount;
        
        [recommendList enumerateObjectsUsingBlock:^(SEGPgcRecommendModel * _Nonnull pgcModel, NSUInteger idx, BOOL * _Nonnull stop) {
            // 不是最后一组 就插入广告
            if (currentIndex == adDisplayModel.showAdvCount && idx < lastGroupIndex) {
                SEGPgcRecommendModel *adModel = [[SEGPgcRecommendModel alloc] init];
                adModel.pgcWidgetType = @(SEGEnumPgcWidgetType_AD).stringValue;
                adModel.adverIndex = adverIndex;
                adverIndex++;
                [handlePGCList addObject:adModel];
            }
            [handlePGCList addObject:pgcModel];
            
            // 计算下标 超过一组就重置
            currentIndex ++;
            if (currentIndex > adDisplayModel.groupCount) {
                currentIndex = 1;
            }
        }];
        return handlePGCList;
    }
    
    return recommendList;
}


/// 计算列表中除去广告后的数量
/// @param pgcList pgc列表
- (NSInteger)getPGCDataCount:(NSArray<SEGPgcRecommendModel *> *)pgcList {
    NSInteger __block count = 0;
    [pgcList enumerateObjectsUsingBlock:^(SEGPgcRecommendModel * _Nonnull pgcModel, NSUInteger idx, BOOL * _Nonnull stop) {
        if (pgcModel.pgcWidgetType == SEGEnumPgcWidgetType_PGC) {
            count ++;
        }
    }];
    return count;
}

@end

